/*
 * @(#)PageInfo.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.config.runtime;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.validator.Validator;

import com.nhncorp.usf.core.Constants;
import com.nhncorp.usf.core.util.StringUtil;


/**
 * 페이지 내에서 사용될 {@link Action} {@link List} 정보.
 *
 * @author Web Platform Development Team.
 */
public class PageInfo {
    private long createdTime;

    /**
     * 페이지 식별정보.
     */
    private String id;

    /**
     * 다른 페이지 include
     */
    private String include;

    /**
     * 페이지 수준의 퍼미션
     */
    private String globalPermission;

    /**
     * 페이지 호출시 기존적으로 수행될 Action 식별자.
     */
    private String defaultActionId = Constants.DEFAULT_ACTION_ID;

    /**
     * Action 수행 성공시 수행되어야 하는 페이지 정보로서 Action 내에 정의된 정보가
     * 없을 경우 사용됨.
     */
    private ResultPageInfos globalSuccessResultInfo;

    /**
     * Action 수행 실패시 수행되어야 하는 페이지 정보로서 Action 내에 정의된 정보가
     * 없을 경우 사용됨.
     */
    private ResultPageInfos globalFailureResultInfo;

    /**
     * 페이지 내에서 사용될 {@link Action} {@link List} 정보.
     */
    private Map<String, Action> actions = new HashMap<String, Action>();

    /**
     * 공통 Action 정보
     */
    private Action commonAction;

    private ScriptInfo pageCommonScriptInfo;

    /**
     * _validation.xml 로 매핑된 Validator. action id -&gt; validator
     * */
	private Map<String, Validator> validators; 

	/**
     * 기본생성자
     */
    public PageInfo() {
        this.createdTime = System.currentTimeMillis();
    }

    /**
     * 생성자
     */
    public PageInfo(String id, String defaultActionId) {
        this();
        this.id = id;
        this.defaultActionId = defaultActionId;
    }

    /**
     * 생성자
     */
    public PageInfo(String id) {
        this();
        this.id = id;
    }

    /**
     * 생성 시간 반환.
     *
     * @return page create time
     */
    public long getCreatedTime() {
        return this.createdTime;
    }

    /**
     * 생성 시간 설정.
     *
     * @param createdTime the page create time
     */
    public void setCreatedTime(long createdTime) {
        this.createdTime = createdTime;
    }

    /**
     * 페이지 식별정보 반환.
     *
     * @return page id
     */
    public String getId() {
        return this.id;
    }

    /**
     * 페이지 식별정보 설정.
     *
     * @param id the page id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 페이지 수준의 퍼미션 반환.
     *
     * @return the global permission name
     */
    public String getGlobalPermission() {
        return this.globalPermission;
    }

    /**
     * 페이지 수준의 퍼미션 설정.
     *
     * @param globalPermission the global permission name
     */
    public void setGlobalPermission(String globalPermission) {
        this.globalPermission = globalPermission;
    }

    /**
     * 기본적으로 수행될 Action 식별자 반환.
     *
     * @return default action id
     */
    public String getDefaultActionId() {
        return this.defaultActionId;
    }

    /**
     * 기본적으로 수행될 Action 식별자 설정
     *
     * @param defaultActionId the default action id
     */
    public void setDefaultActionId(String defaultActionId) {
        this.defaultActionId = defaultActionId;
    }

    /**
     * Aciton 내에 수행 성공에 대한 {@link ResultPageInfos} 가 없는 경우 사용된 {@link ResultPageInfos} 설정.
     *
     * @param resultPageInfo the result page information
     */
    public void setGlobalSuccessResultInfo(ResultPageInfos resultPageInfo) {
        this.globalSuccessResultInfo = resultPageInfo;
    }

    /**
     * Aciton 내에 수행 성공에 대한 {@link ResultPageInfos} 가 없는 경우 사용된 {@link ResultPageInfos} 반환.
     *
     * @return the global success result information
     */
    public ResultPageInfos getGlobalSuccessResultInfo() {
        return this.globalSuccessResultInfo;
    }

    /**
     * Aciton 내에 수행 실패에 대한 {@link ResultPageInfos} 가 없는 경우 사용된 {@link ResultPageInfos} 설정.
     *
     * @param resultPageInfo the result page infomation
     */
    public void setGlobalFailureResultInfo(ResultPageInfos resultPageInfo) {
        this.globalFailureResultInfo = resultPageInfo;
    }

    /**
     * Aciton 내에 수행 실패에 대한 {@link ResultPageInfos} 가 없는 경우 사용된 {@link ResultPageInfos} 반환.
     *
     * @return the global failure result information
     */
    public ResultPageInfos getGlobalFailureResultInfo() {
        return this.globalFailureResultInfo;
    }

    /**
     * 공통 {@link Action} 반환
     *
     * @return Action the common action
     */
    public Action getCommonAction() {
        return commonAction;
    }

    /**
     * 공통 {@link Action} 설정
     *
     * @param commonAction the common Action
     */
    public void setCommonAction(Action commonAction) {
        this.commonAction = commonAction;
    }

    /**
     * 식별자에 대한 {@link Action} 저장.
     *
     * @param id         the action id
     * @param actionInfo the action information
     */
    public void addActionInfo(String id, Action actionInfo) {
        actions.put(id, actionInfo);
    }

    /**
     * 식별자에 대한 {@link Action} 반환.
     *
     * @param id the action id
     * @return Action the action object for id
     * @throws IllegalArgumentException 존재하지 않는 {@link Action} 요청시 던져지는 예외.
     */
    public Action getActionInfo(String id) throws IllegalArgumentException {
        return actions.get(id);
    }

    /**
     * ActionInfo를 저장하고 있는 {@link Map<String, ActionInfo>} 반환.
     *
     * @return action information list
     */
    public Map<String, Action> getActionInfos() {
        return this.actions;
    }

    /**
     * 식별자에 대한 {@link Set} 반환.
     *
     * @return action key list
     */
    public Set<String> getActionKeys() {
        return actions.keySet();
    }

    /**
     * include 반환
     *
     * @return page include file name
     */
    public String getInclude() {
        return include;
    }

    /**
     * include 설정
     *
     * @param include the include file name
     */
    public void setInclude(String include) {
        this.include = include;
    }

    /**
     * 상위 PageInfo 정보를 현재 PageInfo에 include 한다.
     *
     * @param parent 상위 {@link PageInfo} 객체
     */
    public void addParent(PageInfo parent) {

        if (parent == null) {
            throw new IllegalArgumentException("Parent PageInfo must not be null");
        }

        if (StringUtil.isEmpty(this.globalPermission) && StringUtil.isNotEmpty(parent.getGlobalPermission(), false)) {
            this.globalPermission = parent.globalPermission;
        }

        if (this.globalSuccessResultInfo == null && parent.getGlobalSuccessResultInfo() != null) {
            this.globalSuccessResultInfo = parent.getGlobalSuccessResultInfo();
        }

        if (this.globalFailureResultInfo == null && parent.getGlobalFailureResultInfo() != null) {
            this.globalFailureResultInfo = parent.getGlobalFailureResultInfo();
        }

        if (!parent.actions.isEmpty()) {
            Map<String, Action> clone = new HashMap<String, Action>(parent.getActionInfos());
            clone.putAll(this.actions);
            this.actions = clone;
        }
    }

    /**
     * Gets the page common script info.
     *
     * @return the page common script info
     */
    public ScriptInfo getPageCommonScriptInfo() {
        return pageCommonScriptInfo;
    }

    /**
     * Sets the page common script info.
     *
     * @param pageCommonScriptInfo the new page common script info
     */
    public void setPageCommonScriptInfo(ScriptInfo pageCommonScriptInfo) {
        this.pageCommonScriptInfo = pageCommonScriptInfo;
    }
    
    /**
     * @param actionId Action ID
     * @return {@code actionId} 의 validator. 없을 경우 null
     * */
    public Validator getValidator(String actionId) {
    	if (validators == null) {
    		return null;
    	}
    	
    	return validators.get(actionId);
    }

    /**
     * @param actionId Action ID
     * @param validator {@link Validator}
     * */
	public void setValidator(String actionId, Validator validator) {
		if (validators == null) {
			validators = new HashMap<String, Validator>();
		}
		
		validators.put(actionId, validator);
	}
}
